package factory;

import lombok.Data;
import lombok.extern.java.Log;
import org.jdom.Document;
import org.jdom.Element;
import org.jdom.JDOMException;
import org.jdom.input.SAXBuilder;

import java.io.*;
import java.net.URLDecoder;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;

/**
 * 读取配置文件
 */
@Log
@Data
public class Configuration {

    private DatabaseInfo databaseInfo;

    private Map<String, MapperStatement> mapperStatementMap = new ConcurrentHashMap<>();

    public Configuration(String fileName) {
        initConfig(fileName);
    }

    public void initConfig (String fileName) {
        SAXBuilder saxBuilder = new SAXBuilder();
        try {
            InputStream inputStream = Configuration.class.getClassLoader().getResourceAsStream(fileName);
            Document document = saxBuilder.build(inputStream);
            Element rootElement = document.getRootElement();

            //读取数据库的信息
            readDataBaseInfo(rootElement);

            //读取mapper配置文件
            List<String> mappers = getMapperConfig(rootElement);
            for (String mapper : mappers) {
                initMapstatement(mapper);
            }

            Set<String> set = mapperStatementMap.keySet();
            for (String key : set) {
                log.info("key: " +key + " , " + mapperStatementMap.get(key).toString());
            }

        } catch (JDOMException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 读取所有的 mapper 配置文件
     * @param mapper
     */
    public void initMapstatement (String mapper) {
        InputStream inputStream = Configuration.class.getClassLoader().getResourceAsStream(mapper);
        SAXBuilder saxBuilder = new SAXBuilder();
        try {
            Document document = saxBuilder.build(inputStream);
            Element element = document.getRootElement();
            String namespace = element.getAttributeValue("namespace");
            List<Element> children = element.getChildren();

            for(Element ele : children) {
                String operatorType = ele.getName();
                String parameterType = ele.getAttributeValue("parameterType");
                String id = ele.getAttributeValue("id");
                String sql = ele.getContent(0).getValue();
                String resultType = ele.getAttributeValue("resultType");
                MapperStatement mapperStatement = new MapperStatement();
                mapperStatement.setNamespaceId(namespace + "." + id);
                mapperStatement.setOperatorType(operatorType);
                mapperStatement.setSql(sql);
                mapperStatement.setParameterType(parameterType);
                mapperStatement.setResultType(resultType);
                mapperStatementMap.put(namespace + "." + id, mapperStatement);
            }

        } catch (JDOMException e) {
        } catch (IOException e) {
        }

    }

    /**
     * 读取数据库的配置信息
     * @param rootElement
     */
    private void readDataBaseInfo(Element rootElement) {
        Element database = rootElement.getChild("database");
        String driver = database.getChild("driver").getContent(0).getValue();
        String url = database.getChild("url").getContent(0).getValue();
        String userName = database.getChild("username").getContent(0).getValue();
        String password = database.getChild("password").getContent(0).getValue();
        databaseInfo = DatabaseInfo.builder().driver(driver).url(url).userName(userName).password(password).build();
        log.info("数据库的信息：" + databaseInfo.toString());
    }

    /**
     * 根据配置文件读取 mapper.xml 文件
     * @param rootElement
     * @return
     * @throws UnsupportedEncodingException
     */
    private List<String> getMapperConfig (Element rootElement) throws UnsupportedEncodingException {
        List<String> returnMappers = new ArrayList<>();
        String mapperAddress = rootElement.getChild("include").getChild("xml").getContent(0).getValue();
        String prex = mapperAddress.split("/")[1];
        String fileUrl = Configuration.class.getClassLoader().getResource(prex).getFile();
        fileUrl = URLDecoder.decode(fileUrl, "UTF-8");
        File file = new File(fileUrl);
        if (file.isDirectory()) {
            File[] files = file.listFiles();
            for (File file1 : files) {
                String fileMapper = "./" + prex + "/" + file1.getName();
                returnMappers.add(fileMapper);
                log.info(fileMapper);
            }
        }
        return returnMappers;
    }
}
